home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_11_09
/
1109052a
< prev
next >
Wrap
Text File
|
1993-07-06
|
8KB
|
263 lines
// CStrWnd.cpp
// See CStrWnd.h for a definition of what the
// class CStrWnd does
#include "stdhdr.h"
#include "test_r.h"
#include "cstrwnd.h"
#include "strdetab.h"
CStrWnd::CStrWnd (const char * window_name)
{
VERIFY (LoadAccelTable ("CStrWndAccelTable"));
VERIFY (Create (NULL, window_name,
WS_CHILD | WS_VSCROLL, rectDefault,
NULL));
SetFocus ();
current_first_row = 0; current_first_col = 0;
h_scroll_flag = 0;
length_of_longest_line = 0;
}
BEGIN_MESSAGE_MAP (CStrWnd, CMDIChildWnd)
ON_WM_PAINT ()
ON_WM_VSCROLL ()
ON_WM_HSCROLL ()
ON_WM_KEYDOWN ()
ON_COMMAND (CSW_DOC_START, OnDocStart)
ON_COMMAND (CSW_DOC_END, OnDocEnd)
ON_COMMAND (CSW_LINE_RIGHT, OnLineRight)
ON_COMMAND (CSW_LINE_LEFT, OnLineLeft)
END_MESSAGE_MAP ()
afx_msg void CStrWnd::OnPaint ()
{
CPaintDC dc (this);
// Use a fixed-pitch font for better presentation
VERIFY (dc.SelectStockObject(OEM_FIXED_FONT) != NULL);
// First find out number of lines in the window
TEXTMETRIC tm;
VERIFY (dc.GetTextMetrics (&tm));
const int char_height = tm.tmHeight
+ tm.tmExternalLeading;
const int char_width = tm.tmAveCharWidth;
CRect rect;
GetClientRect (rect);
no_of_lines = rect.Height () / char_height;
no_of_chars_in_line = rect.Width () / char_width;
// Set up the tab stop positions
const int tab_interval = 4;
const int no_of_tabs = 120 / tab_interval;
int char_tab_stops [no_of_tabs];
for (int i = 0; i < no_of_tabs; i++)
char_tab_stops [i] = (i + 1) * tab_interval;
// Write a window_full of text
for (int lc = 0;
lc < no_of_lines
&& current_first_row + lc
< text_buffer.GetSize ();
lc++)
{
const int max_line_length = 256;
char out_buf [max_line_length + 1];
int line_length;
// Convert tabs to spaces
strdetab (out_buf, max_line_length,
text_buffer [current_first_row + lc],
no_of_tabs, char_tab_stops,
&line_length);
// Get pointer to first char in line for output
const char * first_char = out_buf
+ current_first_col;
// Update record of longest line length
if (length_of_longest_line < line_length)
length_of_longest_line = line_length;
// Call up horizontal scroll bar if needed
if (line_length > no_of_chars_in_line)
h_scroll_flag = 1;
dc.TextOut (0, lc * char_height, first_char,
line_length - current_first_col);
}
if (h_scroll_flag) ShowScrollBar (SB_HORZ, TRUE);
}
afx_msg void CStrWnd::OnVScroll (UINT nSBCode,
UINT npos,
CScrollBar * pBar)
{
int min_scroll_pos, max_scroll_pos,
max_index = text_buffer.GetSize () - 1,
scrolled = 1;
if (max_index < 0) max_index = 0;
// Cater for no lines in text_buffer
switch (nSBCode)
{
case SB_LINEDOWN:
current_first_row++; break;
case SB_PAGEDOWN:
current_first_row += no_of_lines - 1; break;
case SB_LINEUP:
current_first_row--; break;
case SB_PAGEUP:
current_first_row -= no_of_lines - 1; break;
case SB_THUMBPOSITION:
GetScrollRange (SB_VERT, &min_scroll_pos,
&max_scroll_pos);
current_first_row =
(max_index * (npos - min_scroll_pos))
/ (max_scroll_pos - min_scroll_pos);
break;
default:
// We did nothing, so do not update the window!
scrolled = 0; break;
}
if (scrolled)
{
// Now make sure that the current row is in range
if (current_first_row < 0) current_first_row = 0;
if (current_first_row > max_index)
current_first_row = max_index;
Invalidate (TRUE);
SetVerticalScroll ();
UpdateWindow ();
}
}
afx_msg void CStrWnd::OnHScroll (UINT nSBCode,
UINT npos,
CScrollBar * pBar)
{
int min_scroll_pos, max_scroll_pos,
scrolled = 1;
GetScrollRange (SB_VERT, &min_scroll_pos,
&max_scroll_pos);
switch (nSBCode)
{
case SB_LINERIGHT:
current_first_col++; break;
case SB_PAGERIGHT:
current_first_col += 10; break;
case SB_LINELEFT:
current_first_col--; break;
case SB_PAGELEFT:
current_first_col -= 10; break;
case SB_LEFT:
current_first_col = 0; break;
case SB_RIGHT:
current_first_col = length_of_longest_line - 1;
break;
case SB_THUMBPOSITION:
current_first_col =
((length_of_longest_line - 1)
* (npos - min_scroll_pos))
/ (max_scroll_pos - min_scroll_pos);
break;
default:
// We did nothing, so do not update window!
scrolled = 0; break;
}
if (scrolled)
{
// Now ensure that we are within limits
if (current_first_col < 0) current_first_col = 0;
if (current_first_col >= length_of_longest_line)
current_first_col = length_of_longest_line - 1;
Invalidate (TRUE);
if (h_scroll_flag)
SetScrollPos (SB_HORZ,
((max_scroll_pos - min_scroll_pos)
* current_first_col)
/ (length_of_longest_line -1)
+ min_scroll_pos,
TRUE);
UpdateWindow ();
}
}
afx_msg void CStrWnd::OnKeyDown (UINT nChar,
UINT nRepCnt,
UINT nFlags)
{
switch (nChar)
{
case VK_DOWN:
OnVScroll (SB_LINEDOWN, 0, NULL); break;
case VK_NEXT: // Page down
OnVScroll (SB_PAGEDOWN, 0, NULL); break;
case VK_UP:
OnVScroll (SB_LINEUP, 0, NULL); break;
case VK_PRIOR: // Page up
OnVScroll (SB_PAGEUP, 0, NULL); break;
case VK_LEFT:
OnHScroll (SB_LINELEFT, 0, NULL); break;
case VK_HOME:
OnHScroll (SB_LEFT, 0, NULL); break;
case VK_RIGHT:
OnHScroll (SB_LINERIGHT, 0, NULL); break;
case VK_END:
OnHScroll (SB_RIGHT, 0, NULL); break;
}
}
afx_msg void CStrWnd::OnDocStart ()
{
int min_scroll_pos, max_scroll_pos;
GetScrollRange (SB_VERT, &min_scroll_pos,
&max_scroll_pos);
Invalidate (TRUE);
current_first_row = 0;
SetScrollPos (SB_VERT, min_scroll_pos, TRUE);
UpdateWindow ();
}
afx_msg void CStrWnd::OnDocEnd ()
{
int min_scroll_pos, max_scroll_pos;
GetScrollRange (SB_VERT, &min_scroll_pos,
&max_scroll_pos);
Invalidate (TRUE);
current_first_row = text_buffer.GetUpperBound () - 4;
// Leave 4 lines on the screen
if (current_first_row < 0) current_first_row = 0;
SetScrollPos (SB_VERT, max_scroll_pos, TRUE);
UpdateWindow ();
}
afx_msg void CStrWnd::OnLineRight ()
{OnHScroll (SB_PAGERIGHT, 0, NULL);}
afx_msg void CStrWnd::OnLineLeft ()
{OnHScroll (SB_PAGELEFT, 0, NULL);}
void CStrWnd::UpdateScreen ()
{
current_first_row = text_buffer.GetUpperBound ()
- no_of_lines;
if (current_first_row < 0) current_first_row = 0;
SetVerticalScroll ();
Invalidate (TRUE);
UpdateWindow ();
}
void CStrWnd::SetVerticalScroll ()
{
int min_scroll_pos, max_scroll_pos,
max_index = text_buffer.GetUpperBound ();
GetScrollRange (SB_VERT, &min_scroll_pos,
&max_scroll_pos);
SetScrollPos (SB_VERT,
((max_scroll_pos - min_scroll_pos )
* current_first_row)
/ ((max_index > 0) ? max_index : 1)
+ min_scroll_pos,
TRUE);
}